<template>
  <div @click="clearMenu">
    <a-spin :spinning="loading">
      <a-row :gutter="12" class="header">
        <a-col :span="12">
          <p class="left">
            <share-alt-outlined />
            {{ l('OrganizationTree') }}
          </p>
        </a-col>
        <a-col
          :span="12"
          v-if="isGranted('Pages.Administration.OrganizationUnits.ManageOrganizationTree')"
        >
          <p style="text-align: right">
            <a @click="addUnit()">
              <plus-outlined />
              {{ l('AddRootUnit') }}
            </a>
            <a :title="l('Refresh')" @click="getData()" style="margin-left: 5px; margin-right: 5px">
              <reload-outlined />
            </a>
          </p>
        </a-col>
      </a-row>
      <a-row class="tree">
        <a-tree
          :treeData="treeData"
          showIcon
          draggable
          block-node
          @select="onSelect"
          @rightClick="onRightClick"
          @expand="onExpand"
          @dragstart="DragStart"
          @dragenter="DragEnd"
        >
          <template #icon="{ slots }">
            <folder-outlined v-if="slots?.icon === 'folder'" />
            <folder-open-outlined v-if="slots?.icon === 'folder-open'" />
            <file-outlined v-if="slots?.icon === 'file'" />
          </template>
        </a-tree>
        <div :style="tmpStyle" class="right-click-item" v-if="NodeTreeItem">
          <ul>
            <li @click="editUnit()">
              <edit-outlined />
              <span>
                {{ l('Edit') }}
              </span>
            </li>
            <li @click="addSubUnit()">
              <plus-outlined />
              <span>
                {{ l('AddSubUnit') }}
              </span>
            </li>
            <li @click.stop="deleteProp($event)">
              <a-popconfirm
                placement="right"
                @confirm="deleteconfirm"
                @cancel="clearMenu"
                :ok-text="l('Ok')"
                :cancel-text="l('Cancel')"
              >
                <delete-outlined />
                <template #title>{{ l('ConfirmDeleteWarningMessage') }}</template>
                <span>
                  {{ l('Delete') }}
                </span>
              </a-popconfirm>
            </li>
          </ul>
        </div>
      </a-row>
    </a-spin>
  </div>
</template>

<script lang="ts">
  import { AppComponentBase } from '/@/shared/component-base';
  import {
    MoveOrganizationUnitInput,
    OrganizationUnitListDto,
    OrganizationUnitServiceProxy,
  } from '/@/shared/service-proxies';
  import CreateOrEditOrganiaztionUnit from '../create-or-edit-organization-unit/create-or-edit-organization-unit.vue';
  import {
    ReloadOutlined,
    PlusOutlined,
    DeleteOutlined,
    EditOutlined,
    FolderOpenOutlined,
    FolderOutlined,
    ShareAltOutlined,
    FileOutlined,
  } from '@ant-design/icons-vue';
  import _ from 'lodash';
  import { defineComponent } from 'vue';
  import { Modal } from 'ant-design-vue';
  export default defineComponent({
    name: 'organization-unit-tree-panel',

    components: {
      PlusOutlined,
      DeleteOutlined,
      EditOutlined,
      ReloadOutlined,
      FolderOpenOutlined,
      FolderOutlined,
      ShareAltOutlined,
      FileOutlined,
    },
    mixins: [AppComponentBase],
    data() {
      const NodeTreeItem: any = null;
      const tmpStyle: any = {};
      const currentNode: any = null;
      return {
        organizationUnitServiceProxy: new OrganizationUnitServiceProxy(),
        ouData: new Array<OrganizationUnitListDto>(),
        treeData: [],
        NodeTreeItem: NodeTreeItem, // 右键菜单
        tmpStyle: tmpStyle,
        // 选中的item
        activedNode: new OrganizationUnitListDto(),
        currentNode: currentNode,
        currentCreateOrganization: new OrganizationUnitListDto(),
      };
    },
    created() {
      this.organizationUnitServiceProxy = new OrganizationUnitServiceProxy(this.$apiUrl, this.$api);
      this.$nextTick(() => {
        abp.event.on('reloadOrganizationUnitTree', (data) => {
          if (data) {
            this.getData();
          }
        });
      });
      this.getData();
    },
    beforeUnmount() {
      abp.event.off('reloadOrganizationUnitTree', this.getData);
    },
    methods: {
      getData() {
        this.loading = true;
        this.organizationUnitServiceProxy
          .getAllOrganizationUnitList()
          .finally(() => {
            this.loading = false;
          })
          .then((result) => {
            this.ouData = result.items as Array<OrganizationUnitListDto>;
            this.treeData = this.treeDataMap() as never[];
          });
      },
      /**
       * 重组Tree数据
       */
      treeDataMap() {
        const ouDtataParentIsNull = _.filter(this.ouData, (item) => item.parentId === null);
        return ouDtataParentIsNull.map((item) => this._recursionGenerateTree(item));
      },

      /**
       * 递归重组特性菜单为nzTree数据类型
       * @param item 组织机构项
       */
      _recursionGenerateTree(item) {
        // 叶子节点
        const childs = _.filter(this.ouData, (child) => child.parentId === item.id);
        // 父节点 无返回undefined
        const parentOu = _.find(this.ouData, (p) => p.id === item.parentId);
        const _treeNode = {
          title: item.displayName + '(' + item.memberCount + ')',
          key: item.id.toString(),
          isLeaf: childs && childs.length <= 0,
          slots: {
            icon: childs && childs.length > 0 ? 'folder' : 'file',
          },
          expanded: true,
          isMatched: true,
          code: item.code,
          memberCount: item.memberCount,
          dto: item,
          parent: parentOu,
          children: [],
        };
        if (childs && childs.length) {
          childs.forEach((itemChild: any) => {
            const childItem = this._recursionGenerateTree(itemChild) as never;
            _treeNode.children.push(childItem);
          });
        }
        return _treeNode;
      },
      /**
       * 选中item
       */
      onSelect(selectedKeys, _info) {
        this.activedNode = this.ouData.find(
          (item) => parseInt(item.id) == parseInt(selectedKeys[0]),
        ) as OrganizationUnitListDto;
        this.$emit('selectedNode', this.activedNode);
      },
      /**
       * 展开
       */
      onExpand(onExpandarr) {
        this.resetExpandIcon(this.treeData);
        for (let i in onExpandarr) {
          this.setExpandIcon(onExpandarr[i], this.treeData);
        }
      },
      /**
       * 还原图标
       */
      resetExpandIcon(item) {
        for (let i in item) {
          if (!item[i].isLeaf) {
            item[i].slots.icon = 'folder';
          }
          if (item[i].children.length) {
            this.resetExpandIcon(item[i].children);
          }
        }
      },
      /**
       * 设置图标
       */
      setExpandIcon(id, item) {
        for (let i in item) {
          if (item[i].key == id) {
            item[i].slots.icon = 'folder-open';
          }
          if (item[i].children.length) {
            for (let _j in item[i].children) {
              this.setExpandIcon(id, item[i].children);
            }
          }
        }
      },
      /**
       * 右键事件
       */
      onRightClick({ event, node }: any) {
        const x = event.currentTarget.offsetLeft + event.currentTarget.clientWidth;
        const y = event.currentTarget.offsetTop;
        this.NodeTreeItem = {
          pageX: x,
          pageY: y,
          id: node.dataRef.key,
          title: node.dataRef.title,
          parentOrgId: 0,
        };

        this.tmpStyle = {
          position: 'absolute',
          maxHeight: 40,
          textAlign: 'center',
          left: `${x + 10 - 0}px`,
          top: `${y + 30 - 0}px`,
          display: 'flex',
          flexDirection: 'row',
          'z-index': 999,
        };
        this.activedNode = this.ouData.find(
          (p) => p.id == node.dataRef.key,
        ) as OrganizationUnitListDto;
      },
      /**
       * 用于点击空白处隐藏增删改菜单
       */
      clearMenu() {
        this.NodeTreeItem = null;
      },
      /**
       * 添加组织
       */
      addUnit(activedNode?: any) {
        this.modalHelper
          .create(
            CreateOrEditOrganiaztionUnit,
            {
              organizationUnit: {
                parentId: activedNode ? activedNode.id : '',
                parentDisplayName: activedNode ? activedNode.displayName : '',
              },
            },
            {
              width: '200px',
            },
          )
          .subscribe((res) => {
            if (res) {
              this.getData();
              this.clearMenu();
            }
          });
      },
      /**
       * 编辑组织机构
       */
      editUnit() {
        const canManageOrganizationTree = this.isGranted(
          'Pages.Administration.OrganizationUnits.ManageOrganizationTree',
        );
        if (!canManageOrganizationTree) {
          this.message.error(this.l('YouHaveNoOperatingPermissions'));
          return;
        }
        if (this.activedNode.id) {
          const ouPars = {
            id: parseInt(this.activedNode.id),
            displayName: this.activedNode.displayName,
          };
          this.modalHelper
            .create(CreateOrEditOrganiaztionUnit, {
              organizationUnit: ouPars,
            })
            .subscribe((res) => {
              if (res) {
                this.getData();
              }
            });
        }
      },
      /**
       * 添加子节点
       * @param node 当前选中节点
       */
      addSubUnit() {
        const canManageOrganizationTree = this.isGranted(
          'Pages.Administration.OrganizationUnits.ManageOrganizationTree',
        );
        if (!canManageOrganizationTree) {
          this.notify.success(this.l('YouHaveNoOperatingPermissions'));
          return;
        }
        if (this.activedNode.id) {
          this.addUnit(this.activedNode);
        }
        //this.clearMenu();
      },
      /**
       * 删除组织事件
       */
      deleteProp(e) {
        e.stopPropagation();
      },
      /**
       * 删除组织结构
       */
      deleteconfirm() {
        const canManageOrganizationTree = this.isGranted(
          'Pages.Administration.OrganizationUnits.ManageOrganizationTree',
        );
        if (!canManageOrganizationTree) {
          this.notify.success(this.l('YouHaveNoOperatingPermissions'));
          return;
        }
        if (this.activedNode.id) {
          this.organizationUnitServiceProxy.delete(parseInt(this.activedNode.id)).then(() => {
            this.notify.success(this.l('SuccessfullyDeleted'));
            this.clearMenu();
            this.getData();
          });
        }
      },
      DragStart(node: any) {
        this.currentNode = node.node.dataRef;
      },
      DragEnd(node: any) {
        let moveid: any = null;
        if (node) moveid = node.node.dataRef.dto.id;
        if (node.node.dataRef.dto.id === this.currentNode.dto.id) return;
        Modal.confirm({
          title:
            '确定将' +
            this.currentNode.dto.displayName +
            '发送到' +
            node.node.dataRef.dto.displayName,
          okText: '确认',
          cancelText: '取消',
          onOk: () => {
            let moveinput: MoveOrganizationUnitInput = new MoveOrganizationUnitInput();
            moveinput.id = this.currentNode.dto.id;
            moveinput.newParentId = moveid;
            this.organizationUnitServiceProxy.move(moveinput).then((res) => {
              this.clearMenu();
              this.getData();
              this.notify.success(this.l('SavedSuccessfully'));
            });
            return Promise.resolve();
          },
        });

        // this.MoveOrganizationTree(parentId, this.currentNode).then(() => {
        //     console.info(this.currentNode.dto.id);
        //     return this.organizationUnitServiceProxy.delete(this.currentNode.dto.id)
        // }).then(() => {
        //     this.clearMenu();
        //     this.getData();
        //     this.notify.success(this.l('DragSuccessFully'));
        // }).catch(() => {
        //     this.notify.error(this.l('DragFailed'));
        // })
      },
      // async MoveOrganizationTree(parentId: number, data: any) {//拖拽添加树节点
      //     await this.AddCreateOrganization(parentId, data.dto);
      //     parentId = this.currentCreateOrganization.id;
      //     if (data.children.length > 0) {
      //         for (const key in data.children) {
      //             await this.MoveOrganizationTree(parentId, data.children[key])
      //         }
      //     }
      // },
      // async AddCreateOrganization(parentId: number, dto: any) {//拖拽添加树节点
      //     let createInput: CreateOrganizationUnitInput = new CreateOrganizationUnitInput();
      //     createInput.parentId = parentId;
      //     createInput.displayName = dto.displayName;
      //     await this.organizationUnitServiceProxy.create(createInput).then(res => {
      //         console.info(res);
      //         this.currentCreateOrganization = res;
      //     })
      // }
    },
  });
</script>

<style scoped lang="less">
  .header {
    height: 50px;
    border-bottom: 1px solid #e8e8e8;
    white-space: nowrap;

    p {
      line-height: 50px;
      &.left {
        font-size: 16px;
        color: rgba(0, 0, 0, 0.85);
        font-weight: 500;
        margin-left: 20px;
      }
      a {
        margin-left: 10px;
      }
    }
  }
  .tree {
    margin: 20px;
  }
  .right-click-item {
    position: relative;
    margin: 0;
    padding: 4px 0;
    text-align: left;
    list-style-type: none;
    background-color: #fff;
    background-clip: padding-box;
    border-radius: 4px;
    outline: none;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    -webkit-transform: translate3d(0, 0, 0);

    ul {
      list-style: none;
      margin: 0;
      padding: 0;
      li {
        clear: both;
        margin: 0;
        padding: 5px 12px;
        color: rgba(0, 0, 0, 0.65);
        font-weight: normal;
        font-size: 14px;
        line-height: 22px;
        white-space: nowrap;
        cursor: pointer;
        transition: all 0.3s;
        text-align: left;
      }
    }
  }
</style>
